package controllers;

import java.util.List;

import models.Acudiente;
import models.CalendarioAcademico;
import models.Colegio;
import models.Curso;
import models.Estudiante;
import models.MateriaCurso;
import models.Matricula;
import models.Orientador;
import models.Periodo;
import models.Persona;
import models.Profesor;
import models.Secretario;
import play.db.jpa.Transactional;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Result;
import services.ColegioProcessSrv;
import services.ColegioSrv;
import services.DAO;
import util.annotations.NamedAction;
import actors.UserCreator;

public class CoordinadorCtrl extends Controller {

	private static long getIdColegio() {
		return Long.parseLong(session("idColegio"));
	}

	private static long getIdCalendarioAcademicoActual() {
		return ColegioSrv.getColegio(getIdColegio())
				.getIdCalendarioAcademicoActual();
	}

	@Transactional
	@NamedAction("goNext")
	public static Result goNext() throws InstantiationException,
			IllegalAccessException {
		Colegio c = ColegioSrv.getColegio(Long.parseLong(session("idColegio")));
		List<String> s = ColegioProcessSrv.goNext(c);
		return ok(Json.toJson(s));
	}

	@Transactional
	@NamedAction("read")
	public static Result getEstudiantes(String query) {
		List<Estudiante> res = ColegioSrv.getEstudiantes(getIdColegio(), query);
		return ok(Json.toJson(res));
	}

	@Transactional
	@NamedAction("newEstudiante")
	public static Result newEstudiante() {
		Estudiante e = Json.fromJson(request().body().asJson(),
				Estudiante.class);

		Acudiente a = e.getAcudiente();
		a.setIdColegio(getIdColegio());
		ColegioSrv.crearActorConUsuario(a);
		e.setIdAcudiente(a.getId());
		e.setIdColegio(getIdColegio());
		DAO.persist(e);
		DAO.flush();

		e.setAcudiente(a);
		UserCreator.createUser(a);
		return ok(Json.toJson(e));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getGrados() {

		return ok(Json.toJson(ColegioSrv.getGradosColegio(getIdColegio())));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getCursosGrado(Long idGrado) {
		List<Curso> cursos = ColegioSrv.getCursosGrado(
				getIdCalendarioAcademicoActual(), idGrado);
		if (idGrado == 5l)
			System.out.println(Json.toJson(cursos));
		return ok(Json.toJson(cursos));
	}

	@Transactional
	@NamedAction("newCurso")
	public static Result newCurso() {

		Curso c = Json.fromJson(request().body().asJson(), Curso.class);
		c.setIdCalendarioAcademico(getIdCalendarioAcademicoActual());

		ColegioSrv.newCurso(c);

		return ok(Json.toJson(c));
	}

	@Transactional
	@NamedAction("deleteCurso")
	public static Result deleteCurso(Long idCurso) {

		try {
			Curso c = DAO.find(Curso.class, idCurso);
			if (c.getIdCalendarioAcademico() == getIdCalendarioAcademicoActual()) {
				DAO.remove(c);
				DAO.flush();
				return ok();
			}

			return unauthorized("El curso no se puede borrar. Probablemente tiene estudiantes inscritos");
		} catch (Exception e) {
			return unauthorized("El curso no se puede borrar. Probablemente tiene estudiantes inscritos");
		}
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getCurso(Long idCurso) {
		return ok(Json.toJson(DAO.find(Curso.class, idCurso)));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getMateriasCurso(Long idCurso) {

		return ok(Json.toJson(ColegioSrv.getMateriasCurso(idCurso)));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getProfesores() {
		return ok(Json.toJson(DAO.query(Profesor.class,1, "idColegio",
				getIdColegio())));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getSecretarios() {
		return ok(Json.toJson(DAO.query(Secretario.class,-1, "idColegio",
				getIdColegio())));
	}

	@Transactional
	@NamedAction("newProfesor")
	public static Result newProfesor() {
		Profesor c = Json.fromJson(request().body().asJson(), Profesor.class);
		c.setIdColegio(getIdColegio());
		ColegioSrv.crearActorConUsuario(c);
		return ok(Json.toJson(c));
	}

	@Transactional
	@NamedAction("newSecretario")
	public static Result newSecretario() {
		Secretario c = Json.fromJson(request().body().asJson(),
				Secretario.class);
		c.setIdColegio(getIdColegio());
		ColegioSrv.crearActorConUsuario(c);
		return ok(Json.toJson(c));
	}

	@Transactional
	@NamedAction("newOrientador")
	public static Result newOrientador() {
		Orientador c = Json.fromJson(request().body().asJson(),
				Orientador.class);
		c.setIdColegio(getIdColegio());
		ColegioSrv.crearActorConUsuario(c);
		return ok(Json.toJson(c));
	}

	@Transactional
	@NamedAction("updateMateriaCurso")
	public static Result updateMateriaCurso() {

		MateriaCurso mc = Json.fromJson(request().body().asJson(),
				MateriaCurso.class);
		DAO.merge(mc);
		return ok();
	}

	@Transactional
	@NamedAction("updateCurso")
	public static Result updateCurso(Long idCurso) {
		Curso nc = Json.fromJson(request().body().asJson(), Curso.class);
		DAO.merge(nc);
		return ok();
	}

	@Transactional
	@NamedAction("newMatricula")
	public static Result newMatricula() {
		Matricula m = Json.fromJson(request().body().asJson(), Matricula.class);
		m.setIdCalendarioAcademico(getIdCalendarioAcademicoActual());
		DAO.merge(m);
		return ok(Json.toJson(m));
	}

	@Transactional
	@NamedAction("updateEstudiante")
	public static Result updateEstudiante(Long idEstudiante) {
		Estudiante e = Json.fromJson(request().body().asJson(),
				Estudiante.class);
		e.setId(idEstudiante);
		DAO.merge(e);
		if (e.getAcudiente() != null)
			DAO.merge(e.getAcudiente());
		return ok();
	}

	@Transactional
	@NamedAction("updatePersona")
	public static Result updatePersona(Long idPersona) {
		Persona p = Json.fromJson(request().body().asJson(), Persona.class);
		p.setId(idPersona);
		DAO.merge(p);
		return ok();
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getMaterias() {
		// FIXME agregar el metodo materias grado
		return ok(Json.toJson(ColegioSrv.getMateriasColegio(getIdColegio())));
	}

	@Transactional(readOnly = true)
	@NamedAction("read")
	public static Result getCalendarioAcademicoActual() {
		Colegio c = ColegioSrv.getColegio(getIdColegio());
		CalendarioAcademico p = DAO.find(CalendarioAcademico.class,
				c.getIdCalendarioAcademicoActual());
		return ok(Json.toJson(p));
	}

	@Transactional
	@NamedAction("updateCalendarioAcademico")
	public static Result updateCalendarioAcademico(Long idCalendarioAcademico) {

		CalendarioAcademico p = Json.fromJson(request().body().asJson(),
				CalendarioAcademico.class);
		p.setIdColegio(getIdColegio());
		int i = 1;
		for (Periodo c : p.getPeriodos()) {
			c.setCalendarioAcademico(p);
			c.setNumero(i++);
		}

		DAO.merge(p);
		return ok();
	}
}
